package com.dhcc.common.config;

import java.util.Properties;

import javax.persistence.EntityManager;

import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import com.dhcc.framework.common.config.BaseJpaConfig;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = HisJpaConfig.ENTITY_MANAGER_FACTORY_NAME, transactionManagerRef = HisJpaConfig.TRANSACTION_MANAGER_NAME, basePackages = {
		"com.dhcc.his.entity", "com.dhcc.his.dao" }) // 设置Repository所在位置
@DependsOn({"springContextHolder"})
public class HisJpaConfig extends BaseJpaConfig {

	protected static final String DB_NAME = "his";
	protected static final String[] ENTITY_PACKAGES = { "com.dhcc.his.entity" };
	protected static final String ASPECTJ_EXPRESSION = "execution(* com.dhcc..service..*Service*.*(..))";

	@Override
	protected Properties getProperties() {
		Properties properties = new Properties();
		properties.setProperty("get*", "PROPAGATION_REQUIRES_NEW,-BaseException,-DataBaseException");
		properties.setProperty("find*", "PROPAGATION_REQUIRES_NEW,readOnly");
		properties.setProperty("query*", "PROPAGATION_REQUIRES_NEW,readOnly");
		properties.setProperty("load*", "PROPAGATION_REQUIRES_NEW");
		properties.setProperty("submit*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("save*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("update*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("*delete*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("*add*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("change*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("execute*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("resultParse*", "PROPAGATION_REQUIRED,-BaseException,-DataBaseException");
		properties.setProperty("upgrade", "PROPAGATION_REQUIRES_NEW,-BaseException,-DataBaseException");
		properties.setProperty("*", "PROPAGATION_REQUIRED");
		return properties;
	}

	private static final String ENTITY_MANAGER_NAME = DB_NAME + ENTITY_MANAGER_NAME_SUFFIX;
	static final String ENTITY_MANAGER_FACTORY_NAME = DB_NAME + ENTITY_MANAGER_FACTORY_NAME_SUFFIX;
	static final String TRANSACTION_MANAGER_NAME = DB_NAME + TRANSACTION_MANAGER_NAME_SUFFIX;
	private static final String PERSISTENCE_UNIT_NAME = DB_NAME + PERSISTENCE_UNIT_NAME_SUFFIX;
	private static final String TRANSACTION_INTERCEPTOR_NAME = DB_NAME + TRANSACTION_INTERCEPTOR_NAME_SUFFIX;
	private static final String POINTCUT_ADVISOR_NAME = DB_NAME + POINTCUT_ADVISOR_NAME_SUFFIX;

	@Bean(name = ENTITY_MANAGER_FACTORY_NAME)
	public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
		return super.entityManagerFactory(builder, DB_NAME, PERSISTENCE_UNIT_NAME, ENTITY_PACKAGES);
	}

	@Bean(name = ENTITY_MANAGER_NAME)
	@Override
	public EntityManager entityManager(
			@Qualifier(ENTITY_MANAGER_FACTORY_NAME) LocalContainerEntityManagerFactoryBean entityManagerFactory) {
		return super.entityManager(entityManagerFactory);
	}

	@Bean(name = TRANSACTION_MANAGER_NAME)
	@Override
	public PlatformTransactionManager transactionManager(
			@Qualifier(ENTITY_MANAGER_FACTORY_NAME) LocalContainerEntityManagerFactoryBean entityManagerFactory) {
		return super.transactionManager(entityManagerFactory);
	}

	@Bean(name = TRANSACTION_INTERCEPTOR_NAME)
	@Override
	public TransactionInterceptor transactionInterceptor(
			@Qualifier(TRANSACTION_MANAGER_NAME) PlatformTransactionManager transactionManager) {
		return super.transactionInterceptor(transactionManager);
	}

	@Bean(name = POINTCUT_ADVISOR_NAME)
	@Override
	public DefaultPointcutAdvisor pointcutAdvisor(
			@Qualifier(TRANSACTION_INTERCEPTOR_NAME) TransactionInterceptor transactionInterceptor) {
		return super.pointcutAdvisor(transactionInterceptor, ASPECTJ_EXPRESSION);
	}

}
